#pragma once
#include<iostream>
#include<assert.h>
namespace abc
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		const_iterator begin()const
		{
			return _start;
		}
		const_iterator end()const
		{
			return _finish;
		}
		bool empty()
		{
			return capacity() == 0;
		}
		vector()
		{
		}
		vector(const vector<T>& v1)
		{
			reserve(v1.capacity());
			for (auto e : v1)
			{
				push_back(e);
			}
		}
		~vector()
		{
			delete[]_start;
			_start = _finish = _endofstorage = nullptr;
		}
		size_t size()const
		{
			return _finish - _start;
		}
		size_t capacity()const
		{
			return _endofstorage - _start;
		}
		void reserve(int n)
		{
			if (n > size())
			{
				iterator tmp=new T[n];
				int end_size = size();
				memcpy(tmp, _start, sizeof(T) * size());
				delete[]_start;
				_start = tmp;
				_finish = tmp + end_size;
				_endofstorage = tmp + n;
			}
			else
			{

			}
		}
		void pop_back()
		{
			assert(!empty());
			_finish--;
		}
		T& operator[](size_t n)
		{
			assert(n<size());
			return *(_start+n);
		}
		const T& operator[](size_t n)const
		{
			assert(n < size());
			return *(_start + n);
		}
		void resize(size_t n,const T& tmp)
		{
			if (n>size())
			{
				reserve(n);
			    iterator end=_finish + n;
				while (_finish != end)
				{
					push_back(tmp);
				}
			}
			else
			{
				_finish = _start+n;
			}
		}
		void insert(iterator pos, const T& val)
		{
			assert(pos <= _finish);
			assert(pos >= _start);

			if (_finish == _endofstorage)
			{
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : 2 * capacity());
				pos=_start+len;
			}
			int i = 0;
			while (_finish - i >= pos)
			{
				*(_finish - i) = *(_finish - i - 1);
				i++;
			}
			*(pos) = val;
			_finish++;
		}
		void erase(iterator pos)
		{
			assert(pos < _finish);
			assert(pos >= _start);
		
			int i = 0;
			while(pos+i+1!=_finish)
			{
				*(pos + i) = *(pos + i + 1);
				i++;
			}
			_finish--;

		}
		void swap(vector<T> v1)
		{
			std::swap(v1._start, _start);
			std::swap(v1._finish, _finish);
			std::swap(v1._endofstorage, _endofstorage);

		}
		//void insert(size_t pos,const T& val)
		//{
		//	assert(pos<=size());
		//	if (_finish == _endofstorage)
		//	{
		//		reserve(capacity() == 0 ? 4 : 2 * capacity());
		//	}
		//	int i = 0;
		//	while (_finish - i >= pos + _start)
		//	{
		//		*(_finish - i) = *(_finish - i - 1);
		//		i++;
		//	}
		//	*(_start+pos) = val;
		//	_finish++;
		//}
		void push_back(const T& a)
		{
			if (_finish == _endofstorage)
			{
				reserve(capacity()==0?4:2*capacity());
			}
			*_finish = a;
			++_finish;
		}
	private:
		iterator _start=nullptr;
		iterator _finish=nullptr;
		iterator _endofstorage = nullptr;
	};
}
